Najczęściej wykorzystywanymi bateriami są baterie litowe. Można dla nich zaobserwować największe średnie napięcie. Często bada się także baterie oparte na magnezie, cynku, wapniu czy sodzie. Baterie oparte na magnezie potrafią osiągnąć znacznie większe wartości zmiany objętności. Model regresji liniowej oparty na średnim napięciu, pojemnościach i one-hot-encodingu głównego jonu średnio radzi sobie w przewidywaniu gęstocíć energii w odniesieniu do masy baterii.
library(knitr)
library(DT)
library(dplyr)
library(ggplot2)
library(gridExtra)
library(corrplot)
library(caret)
library(tidyr)
set.seed(2024)
df = read.csv("mp_batteries.csv")
prettyTable(df)
Average.Voltage, Gravimetric.Energy, Volumetric.Energy przyjmują ujemne wartości z powodu kierunku prądu. Kierunek prądu nie będzie przydatny w tej analizie, więc zastostuję transformację, aby wszystkie wartości były nieujemne.
df <- df %>%
mutate(
Average.Voltage = abs(Average.Voltage),
Gravimetric.Energy = abs(Gravimetric.Energy),
Volumetric.Energy = abs(Volumetric.Energy)
)
knitr::kable(summary(df))
| Battery.ID | Battery.Formula | Working.Ion | Formula.Charge | Formula.Discharge | Max.Delta.Volume | Average.Voltage | Gravimetric.Capacity | Volumetric.Capacity | Gravimetric.Energy | Volumetric.Energy | Atomic.Fraction.Charge | Atomic.Fraction.Discharge | Stability.Charge | Stability.Discharge | Steps | Max.Voltage.Step | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Length:4351 | Length:4351 | Length:4351 | Length:4351 | Length:4351 | Min. : 0.00002 | Min. : 0.00306 | Min. : 5.176 | Min. : 24.08 | Min. : 0.205 | Min. : 0.936 | Min. :0.00000 | Min. :0.007407 | Min. :0.00000 | Min. :0.00000 | Min. :1.000 | Min. : 0.0000 | |
| Class :character | Class :character | Class :character | Class :character | Class :character | 1st Qu.: 0.01747 | 1st Qu.: 2.23367 | 1st Qu.: 88.108 | 1st Qu.: 311.62 | 1st Qu.: 215.518 | 1st Qu.: 834.453 | 1st Qu.:0.00000 | 1st Qu.:0.086957 | 1st Qu.:0.03301 | 1st Qu.:0.01952 | 1st Qu.:1.000 | 1st Qu.: 0.0000 | |
| Mode :character | Mode :character | Mode :character | Mode :character | Mode :character | Median : 0.04203 | Median : 3.30211 | Median : 130.691 | Median : 507.03 | Median : 403.139 | Median : 1467.835 | Median :0.00000 | Median :0.142857 | Median :0.07319 | Median :0.04878 | Median :1.000 | Median : 0.0000 | |
| NA | NA | NA | NA | NA | Mean : 0.37531 | Mean : 3.13564 | Mean : 158.291 | Mean : 610.62 | Mean : 452.161 | Mean : 1691.783 | Mean :0.03986 | Mean :0.159077 | Mean :0.14257 | Mean :0.12207 | Mean :1.167 | Mean : 0.1503 | |
| NA | NA | NA | NA | NA | 3rd Qu.: 0.08595 | 3rd Qu.: 4.02015 | 3rd Qu.: 187.600 | 3rd Qu.: 722.75 | 3rd Qu.: 614.416 | 3rd Qu.: 2252.257 | 3rd Qu.:0.04762 | 3rd Qu.:0.200000 | 3rd Qu.:0.13160 | 3rd Qu.:0.09299 | 3rd Qu.:1.000 | 3rd Qu.: 0.0000 | |
| NA | NA | NA | NA | NA | Max. :293.19322 | Max. :54.56883 | Max. :2557.627 | Max. :7619.19 | Max. :5926.950 | Max. :18305.898 | Max. :0.90909 | Max. :0.993333 | Max. :6.48710 | Max. :6.27781 | Max. :6.000 | Max. :26.9607 |
Zbiór danych zawiera 4351 rekordów, w tym 0 z wartościami pustymi.
working.ion.count <- df %>%
count(Working.Ion) %>%
rename(Count = n)
ggplot(
working.ion.count,
aes(
x = Working.Ion,
y = Count,
fill = Working.Ion
)
) +
geom_col() +
labs(
title = "Ilość unikalnych głównych jonów",
x = "Główny jon",
y = "Ilość"
)
Zbiór danych zawiera najwięcej baterii opartych na licie.
Przedział wartości zmiany objętości jest bardzo duży. Wartości
poniżej 1 dotyczą 98% zbioru danych. Ale największą wartością jest
293.1932179. Z tego powodu histogram nie za dobrze przedstawi rozkład
wartości.
Warto zastanowić się co ma wpływ na bardzo wysokie wartości
Max Delta Volume. W dalszej części analizy przyjrzymy się
korelacji pomiędzy zmiennymi, aby odpowiedzieć sobie na to pytanie. W
tej sekcji sprawdzimy jedynie statystyki Max Delta Volume
dla poszczególnych głównych jonów.
df %>%
group_by(Working.Ion) %>%
summarise(
Min.Max.Delta.Volume = min(Max.Delta.Volume),
Max.Max.Delta.Volume = max(Max.Delta.Volume),
Mean.Max.Delta.Volume = mean(Max.Delta.Volume),
SD.Max.Delta.Volume = sd(Max.Delta.Volume),
Count = n()
) %>%
prettyTable
Magnes zdecydowanie wyróżnia się na tle innych jonów.
df %>%
group_by(Working.Ion) %>%
summarise(
Min.Average.Voltage = min(Average.Voltage),
Max.Average.Voltage = max(Average.Voltage),
Mean.Average.Voltage = mean(Average.Voltage),
SD.Average.Voltage = sd(Average.Voltage),
Count = n()
) %>%
prettyTable
Tym razem największe średnie napięcie można zaobserwować dla baterii litowych.
# Histogram dla Gravimetric.Capacity
hist_gravimetric <- ggplot(df, aes(x = Gravimetric.Capacity)) +
geom_histogram(bins=30) +
labs(title = "Histogram Gravimetric.Capacity", x = "Geometric Capacity", y = "Częstotliwość")
# Histogram dla Volumetric.Capacity
hist_volumetric <- ggplot(df, aes(x = Volumetric.Capacity)) +
geom_histogram(bins=30) +
labs(title = "Histogram Volumetric.Capacity", x = "Volumetric Capacity", y = "Częstotliwość")
grid.arrange(hist_gravimetric, hist_volumetric, ncol=2)
# Histogram dla Gravimetric.Energy
hist_gravimetric <- ggplot(df, aes(x = Gravimetric.Energy)) +
geom_histogram(bins=30) +
labs(title = "Histogram Gravimetric.Energy", x = "Geometric Energy", y = "Częstotliwość")
# Histogram dla Volumetric.Energy
hist_volumetric <- ggplot(df, aes(x = Volumetric.Energy)) +
geom_histogram(bins=30) +
labs(title = "Histogram Volumetric.Energy", x = "Volumetric Energy", y = "Częstotliwość")
grid.arrange(hist_gravimetric, hist_volumetric, ncol=2)
ggplot(df) +
geom_histogram(aes(x = Stability.Charge),
fill = "yellow", color = "black", alpha = 0.5,
bins=30) +
geom_histogram(aes(x = Stability.Discharge),
fill = "red", color = "black", alpha = 0.5,
bins = 30) +
labs(title = "Histogramy Stability.Charge i Stability.Discharge",
x = "Wartości", y = "Częstotliwość")
selected_df <- df %>%
select(
Max.Delta.Volume,
Average.Voltage,
Gravimetric.Capacity,
Volumetric.Capacity,
Gravimetric.Energy,
Volumetric.Energy,
Stability.Charge,
Stability.Discharge,
Max.Voltage.Step
)
cor_matrix <- cor(selected_df)
cor_matrix[lower.tri(cor_matrix, diag = TRUE)] <- NA
corrplot(cor_matrix, method = "circle", type = "upper",
tl.cex = 0.8, number.cex = 0.7, diag = FALSE,
tl.col = "black",
addCoef.col = "black",
col=colorRampPalette(c("cornflowerblue", "white", "indianred1"))(200))
Można zaobserwować wysoką korelację pomiędzy Gravimetric.Energy i Volumetric.Energy. Jak również Gravimetric.Capacity i Volumetric.Capacity. A także Stability.Charge i Stability.Discharge. Co ciekawe można także zaobserwować całkiem wysoką korelację pomiędzy Average.Voltage i Gravimetric.Energy.
data = df %>%
select(
Working.Ion,
Average.Voltage,
Gravimetric.Capacity,
Volumetric.Capacity,
Gravimetric.Energy
) %>%
mutate(Working.Ion = as.factor(Working.Ion)) %>%
mutate(value = 1) %>% # one-hot-encoding
spread(Working.Ion, value, fill = 0 )
trainIndex <- createDataPartition(data$Gravimetric.Energy, p = 0.8, list = FALSE)
trainData <- data[trainIndex, ]
testData <- data[-trainIndex, ]
preProcessParams <- preProcess(trainData[, c("Average.Voltage", "Gravimetric.Capacity",
"Volumetric.Capacity")],
method = "range")
trainDataScaled <- predict(preProcessParams, trainData)
testDataScaled <- predict(preProcessParams, testData)
model <- lm(Gravimetric.Energy ~ ., data = trainDataScaled)
predictions <- predict(model, newdata = testDataScaled)
R2 <- cor(predictions, testDataScaled$Gravimetric.Energy)^2
Model uzyskał wartość R^2 równą `r R2.
ggplot(data.frame(Actual = testData$Gravimetric.Energy, Predicted = predictions), aes(x = Actual, y = Predicted)) +
geom_point() +
geom_abline(slope = 1, intercept = 0, color = "red") +
labs(title = "Rzeczywiste vs przewidywane wartości",
x = "Rzeczywiste wartości",
y = "Przewidywane wartości")